<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { NModal, NForm, NFormItem, NInput, useMessage } from 'naive-ui'
import type { FormInst, FormItemRule, FormRules } from 'naive-ui'
import type {
  CreateUserPayloadType,
  QueryUserItemType,
  updateUserPayloadType
} from '@/types/api/user'
import { createUserApi, updateUserApi } from '@/api/user'
import RoleSelect from '@/components/RoleSelect/index.vue'

const message = useMessage()

type PropsType = {
  type: 'create' | 'update'
  record: QueryUserItemType | null
  onOk?: Function
}
const props = defineProps<PropsType>()

const title = computed(() => (props.type === 'create' ? '新增' : '编辑'))
const showModal = ref(false)

const formRef = ref<FormInst | null>(null)
const formValue = ref<CreateUserPayloadType & { roleIds: string[]; confirmPassword: string }>({
  username: '',
  password: '',
  confirmPassword: '',
  email: '',
  phoneNumber: '',
  roleIds: []
})
const formRules: FormRules = {
  username: {
    required: true,
    message: '请输入用户名',
    trigger: ['input']
  },
  password: {
    required: true,
    message: '请输入密码',
    trigger: ['input']
  },
  confirmPassword: {
    trigger: ['input'],
    validator(_rule: FormItemRule) {
      const confirmPassword = formValue.value.confirmPassword
      const password = formValue.value.password
      if (!confirmPassword) {
        return new Error('请再次输入密码')
      }
      if (confirmPassword !== password) {
        return new Error('两次输入的密码不同')
      }
      return true
    }
  },
  email: {
    required: true,
    message: '请输入邮箱',
    trigger: ['input']
  },
  phoneNumber: {
    required: true,
    message: '请输入手机号',
    trigger: ['input']
  },
  roleIds: {
    message: '请选择角色',
    trigger: ['blur', 'change'],
    validator() {
      return formValue.value.roleIds.length > 0
    }
  }
}

watch(showModal, (val) => {
  if (val) {
    // 弹窗打开
    if (props.record) {
      formValue.value.username = props.record.username
      formValue.value.email = props.record.email
      formValue.value.phoneNumber = props.record.phoneNumber
      formValue.value.roleIds = props.record.roles.map((role) => role.id)
    } else {
      formValue.value.username = ''
      formValue.value.email = ''
      formValue.value.phoneNumber = ''
      formValue.value.roleIds = []
    }
  }
})

const handleOk = async () => {
  const { onOk, type, record } = props

  await formRef.value?.validate()
  const { username, email, phoneNumber, password, roleIds } = formValue.value

  if (type === 'create') {
    // 新增
    const payload: CreateUserPayloadType = {
      username,
      password,
      email,
      phoneNumber,
      roleIds
    }
    await createUserApi(payload)
  } else {
    // 编辑
    const payload: updateUserPayloadType = {
      id: record?.id || '',
      username,
      email,
      phoneNumber,
      roleIds
    }
    await updateUserApi(payload)
  }
  message.success(`${title.value}成功`)
  showModal.value = false
  onOk && onOk()
}

defineExpose({
  showModal
})
</script>

<template>
  <NModal
    v-model:show="showModal"
    :title="title"
    preset="dialog"
    positive-text="确认"
    negative-text="取消"
    @positiveClick="handleOk"
  >
    <div style="margin-top: 20px">
      <NForm ref="formRef" :model="formValue" :rules="formRules">
        <NFormItem label="用户名" path="username">
          <NInput v-model:value="formValue.username" placeholder="请输入用户名" :clearable="true" />
        </NFormItem>
        <template v-if="props.type === 'create'">
          <NFormItem label="密码" path="password">
            <NInput
              v-model:value="formValue.password"
              placeholder="请输入密码"
              :clearable="true"
              type="password"
            />
          </NFormItem>
          <NFormItem label="再次确认密码" path="confirmPassword">
            <NInput
              v-model:value="formValue.confirmPassword"
              placeholder="请再次输入密码"
              :clearable="true"
              type="password"
              :disabled="!formValue.password"
            />
          </NFormItem>
        </template>

        <NFormItem label="邮箱" path="email">
          <NInput v-model:value="formValue.email" placeholder="请输入邮箱" :clearable="true" />
        </NFormItem>
        <NFormItem label="手机号" path="phoneNumber">
          <NInput
            v-model:value="formValue.phoneNumber"
            placeholder="请输入手机号"
            :clearable="true"
          />
        </NFormItem>
        <NFormItem label="角色" path="roleIds">
          <RoleSelect v-model:value="formValue.roleIds" />
        </NFormItem>
      </NForm>
    </div>
  </NModal>
</template>

<style lang="scss" scoped></style>
